package cn.tedu.justone.pack01;

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;

/**
 * ZZ：JustOne
 * VX：Andylau2020smile
 * DY：JustOne2018
 * ZT：《》
 */
public class Demo32_Volatile禁止代码重排序测试 {

    //Volatile禁止代码重排序的测试
    //Volatile禁止代码重排序的测试
    //Volatile禁止代码重排序的测试
    //
    //测试方案：
    // 1,测试方案一，8个变量都正常写，用死循环运行后出现x==0&&y==0的情况，
    //   这说明代码重排序了，将：
    //   a = 1;
    //   a1 = 101;
    //   a2 = 102;
    //   x = b;
    //   由于x=b耗时量更轻，所以提前了，重排序成了：
    //   x = b;
    //   a = 1;
    //   a1 = 101;
    //   a2 = 102; 即是把 x = b;前置了，否则不可能出现 x==0&&y==0
    //
    // 2,测试方案二，在声明a2=0; b2=0时加上volatile，并改变run()方法中的顺序为：
    //   a, x, a1, a2, 测试会看到还是会出现 x==0&&y==0，是因为重排序为：
    //   x, a, a1, a2, 说明volatile之前的代码会重排序。
    //   用类似的方法可以测出 volatile 之后的代码也会会发生重排序，在此就不写了。
    //
    // 3,测试方案三，run()方法中的顺序为：
    //   a, a1, a2, x, 也即是用 volatile a2对 a和x进行了隔离，运行，
    //   发现不会出现x==0&&y==0
    //   说明volatile关键字之前的代码不可以重排到volatile之后
    //   本次测试中a1是多余的，可以删除。
    //
    //

    private static long a = 0;
    private static long a1 = 0;
    private volatile static long a2 = 0;

    private static long b = 0;
    private static long b1 = 0;
    private volatile static long b2 = 0;

    private static long x = 0;
    private static long y = 0;

    private static long count = 0;

    public static void main(String[] args) throws InterruptedException {
        while(true){
            a = 0;
            a1 = 0;
            a2 = 0;
            b = 0;
            b1 = 0;
            b2 = 0;
            x = 0;
            y = 0;
            count++;

            Thread t1 = new Thread(){
                @Override
                public void run() {
                    a = 1;
                    a1 = 101;
                    a2 = 102;//v
                    x = b;
                }
            };

            Thread t2 = new Thread(){
                @Override
                public void run() {
                    b = 1;
                    b1 = 201;
                    b2 = 202;//v
                    y = a;
                }
            };

            t1.start();
            t2.start();
            t1.join();
            t2.join();

            String str = "count = " + count + "," + x + "," + y;

            if(x==0 && y==0){
                System.out.println("---"+str);
                break;
            }else{
                System.out.println(str);
            }
        }

    }
}














